package com.gaojinqi.base.core.jpa.factory;

/**
 * 创建一个自定义的FactoryBean去替代默认的工厂类 <BR>
 *
 * @author gao.jinqi
 * @date 2020-03-22 00:39
 */

import com.gaojinqi.base.core.jpa.impl.BaseRepositoryImpl;
import com.gaojinqi.base.core.jpa.impl.BaseTreeRepositoryImpl;
import com.gaojinqi.base.common.model.BaseTreeEntity;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.support.JpaRepositoryFactory;
import org.springframework.data.jpa.repository.support.JpaRepositoryFactoryBean;
import org.springframework.data.jpa.repository.support.SimpleJpaRepository;
import org.springframework.data.repository.core.RepositoryInformation;
import org.springframework.data.repository.core.RepositoryMetadata;
import org.springframework.data.repository.core.support.RepositoryFactorySupport;

import javax.persistence.EntityManager;
import java.io.Serializable;

public class CustomRepositoryFactoryBean<R extends JpaRepository<T, I>, T, I extends Serializable>
        extends JpaRepositoryFactoryBean<R, T, I> {

    /**
     * @param repositoryInterface
     */
    public CustomRepositoryFactoryBean(Class<? extends R> repositoryInterface) {
        super(repositoryInterface);
    }

    @Override
    protected RepositoryFactorySupport createRepositoryFactory(final EntityManager entityManager) {
        return new JpaRepositoryFactory(entityManager) {

            @Override
            protected SimpleJpaRepository<T, I> getTargetRepository(RepositoryInformation information,
                                                                    EntityManager entityManager) {
                Class<T> domainClass = (Class<T>) information.getDomainType();
                if (BaseTreeEntity.class.isAssignableFrom(domainClass)) {
                    return new BaseTreeRepositoryImpl(domainClass, entityManager);
                }
                return new BaseRepositoryImpl<>(domainClass, entityManager);
            }

            @Override
            public Class<?> getRepositoryBaseClass(RepositoryMetadata metadata) {
                if (BaseTreeEntity.class.isAssignableFrom(metadata.getDomainType())) {
                    return BaseTreeRepositoryImpl.class;
                }
                return BaseRepositoryImpl.class;
            }
        };
    }

}

